package org.luxor.common.netty.protocol.handler;

import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.luxor.common.netty.protocol.message.NettyPingMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 超时处理器
 *
 * @author Mr.yan @date 2024/2/23
 */
@ChannelHandler.Sharable
public class IdleTimeoutHandler extends ChannelDuplexHandler {
    private static final Logger log = LoggerFactory.getLogger(IdleTimeoutHandler.class);
    private final String sid;
    private final boolean isClient;

    public IdleTimeoutHandler(String sid, boolean isClient) {
        this.sid = sid;
        this.isClient = isClient;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            if (e.state() == IdleState.READER_IDLE) {
                if (isClient) {
                    log.debug("[id:{}({})] The client send MessageType:'ping'.", ctx.channel().id(), this.sid);
                    // 发送心跳消息
                    ctx.writeAndFlush(NettyPingMessage.from());
                } else {
                    log.debug("[id:{}({})] The channel is closed because it is idle time-out. Wait for the client to reconnect.", ctx.channel().id(), this.sid);
                    ctx.channel().close();
                }
            }
        }
    }
}
